import fs from 'fs-extra';
import path from 'path';
import { ComponentParser } from '../parser/parser';
import { VueComponent, ComponentProp, ComponentEvent, ComponentSlot, ComponentMethod } from '../core/types';

/**
 * 生成Markdown文档
 * @param scanPaths 要扫描的组件路径
 * @param outputPath 输出路径
 * @param vueVersion Vue版本
 * @param customParser 自定义解析器实例（可选）
 */
export async function generateMarkdown(
  scanPaths: string[],
  outputPath: string,
  vueVersion: string = 'auto',
  customParser?: ComponentParser
): Promise<void> {
  // 使用提供的解析器或创建新解析器
  const parser = customParser || new ComponentParser(scanPaths, vueVersion);
  
  // 如果使用的是新创建的解析器，需要解析组件
  if (!customParser) {
    await parser.parseComponents();
  }
  
  const components = parser.getComponentList();

  // 确保输出目录存在
  await fs.ensureDir(outputPath);

  // 生成索引文件
  await generateIndexFile(components, outputPath);

  // 为每个组件生成文档文件
  for (const component of components) {
    await generateComponentFile(component, outputPath);
  }
}

/**
 * 生成索引文件
 * @param components 组件列表
 * @param outputPath 输出路径
 */
async function generateIndexFile(components: VueComponent[], outputPath: string): Promise<void> {
  let content = `# 组件文档\n\n`;
  content += `生成时间: ${new Date().toLocaleString()}\n\n`;
  content += `## 组件列表\n\n`;

  // 按名称排序组件
  const sortedComponents = [...components].sort((a, b) => a.name.localeCompare(b.name));

  for (const component of sortedComponents) {
    content += `- [${component.name}](${component.name}.md) - ${component.description || '无描述'}\n`;
  }

  await fs.writeFile(path.join(outputPath, 'README.md'), content, 'utf-8');
}

/**
 * 生成组件文档文件
 * @param component 组件信息
 * @param outputPath 输出路径
 */
async function generateComponentFile(component: VueComponent, outputPath: string): Promise<void> {
  let content = `# ${component.name}\n\n`;
  
  // 基本信息
  content += `## 基本信息\n\n`;
  content += `- **描述**: ${component.description || '无描述'}\n`;
  content += `- **文件路径**: \`${component.filePath}\`\n`;
  content += `- **Vue版本**: ${component.vueVersion}\n`;
  content += `- **创建时间**: ${new Date(component.createdAt).toLocaleString()}\n`;
  content += `- **更新时间**: ${new Date(component.updatedAt).toLocaleString()}\n\n`;

  // 属性
  content += `## 属性\n\n`;
  if (component.props.length > 0) {
    content += `| 名称 | 类型 | 默认值 | 是否必填 | 描述 |\n`;
    content += `| --- | --- | --- | --- | --- |\n`;
    for (const prop of component.props) {
      // 添加可能的值的显示
      const valuesStr = prop.values && prop.values.length > 0 
        ? `<br>可选值: ${prop.values.join(', ')}` 
        : '';
      
      content += `| ${prop.name} | \`${prop.type}\` | ${prop.defaultValue ? `${prop.defaultValue}` : '-'} | ${prop.required ? '是' : '否'} | ${prop.description || '-'}${valuesStr} |\n`;
    }
    content += '\n';
  } else {
    content += `该组件没有定义属性。\n\n`;
  }

  // 事件
  content += `## 事件\n\n`;
  if (component.events.length > 0) {
    for (const event of component.events) {
      content += `### ${event.name}\n\n`;
      content += `${event.description || '无描述'}\n\n`;
      
      if (event.arguments.length > 0) {
        content += `**参数:**\n\n`;
        content += `| 名称 | 类型 | 描述 |\n`;
        content += `| --- | --- | --- |\n`;
        for (const arg of event.arguments) {
          content += `| ${arg.name} | \`${arg.type}\` | ${arg.description || '-'} |\n`;
        }
        content += '\n';
      }
    }
  } else {
    content += `该组件没有定义事件。\n\n`;
  }

  // 插槽
  content += `## 插槽\n\n`;
  if (component.slots.length > 0) {
    for (const slot of component.slots) {
      content += `### ${slot.name}\n\n`;
      content += `${slot.description || '无描述'}\n\n`;
      
      if (slot.bindings.length > 0) {
        content += `**作用域:**\n\n`;
        content += `| 名称 | 类型 | 描述 |\n`;
        content += `| --- | --- | --- |\n`;
        for (const binding of slot.bindings) {
          content += `| ${binding.name} | \`${binding.type}\` | ${binding.description || '-'} |\n`;
        }
        content += '\n';
      }
    }
  } else {
    content += `该组件没有定义插槽。\n\n`;
  }

  // 方法
  content += `## 方法\n\n`;
  if (component.methods.length > 0) {
    for (const method of component.methods) {
      content += `### ${method.name}\n\n`;
      content += `${method.description || '无描述'}\n\n`;
      
      content += `**签名:**\n\n`;
      
      let signature = `${method.name}(`;
      if (method.params.length > 0) {
        signature += method.params.map(param => param.name).join(', ');
      }
      signature += `): ${method.returns?.type || 'void'}`;
      
      content += `\`\`\`typescript\n${signature}\n\`\`\`\n\n`;
      
      if (method.params.length > 0) {
        content += `**参数:**\n\n`;
        content += `| 名称 | 类型 | 默认值 | 描述 |\n`;
        content += `| --- | --- | --- | --- |\n`;
        for (const param of method.params) {
          content += `| ${param.name} | \`${param.type}\` | ${param.defaultValue ? `\`${param.defaultValue}\`` : '-'} | ${param.description || '-'} |\n`;
        }
        content += '\n';
      }
      
      content += `**返回值:**\n\n`;
      content += `\`${method.returns?.type || 'void'}\` - ${method.returns?.description || '-'}\n\n`;
    }
  } else {
    content += `该组件没有定义公共方法。\n\n`;
  }

  // 示例
  if (component.example) {
    content += `## 示例\n\n`;
    content += `\`\`\`vue\n${component.example}\n\`\`\`\n`;
  }

  await fs.writeFile(path.join(outputPath, `${component.name}.md`), content, 'utf-8');
} 